<template>
  <div>
    <el-dialog title="脚本编辑"
               width="80%"
               top="5vh"
               :visible.sync="visible"
               @close="close"
               :modal-append-to-body="true"
               :append-to-body="true">
      <div class="dialog-script">
        <div class="dialog-script-tip">
          <el-input size="mini" placeholder="输入关键字进行过滤"
                    v-model="filterText"></el-input>

          <div class="dst-tree">
            <el-tree ref="tree_"
                     :data="treeData"
                     :props="treeProps"
                     :default-expand-all="true"
                     :expand-on-click-node="false"
                     :filter-node-method="filterNode">
              <template slot="default" slot-scope="{node,data}">
                <el-popover
                    v-if="!data.unShowPopover"
                    placement="right"
                    width="400"
                    trigger="hover"
                    content="这是一段内容,这是一段内容,这是一段内容,这是一段内容。">
                  <div>
                    <p>
                      <span style="font-weight: bold;font-size: 16px">
                          {{ data.details.label }}
                      </span>
                      &nbsp;&nbsp;
                      <span style="font-family: 'Inconsolata'">{{ data.details.subLabel }}</span>
                    </p>
                    <p>
                        <span style="font-weight: bold;font-size: 16px">
                           示例
                        </span>
                      <p style="color: #9876AA;font-family: 'Inconsolata'" v-html="data.details.script"></p>
                    </p>
                  </div>
                  <span slot="reference"> {{ data.label }}</span>
                </el-popover>
                <span v-else>{{ data.label }}</span>
              </template>
            </el-tree>
          </div>
        </div>

        <div class="dialog-script-con" v-if="tabs==='script'">
          <template v-for="item in com">
            <template v-if="item === 'methods'">
              <template v-for="(it,ix) in pageScript[item]">
                <code-editor @input="v=>pageScript[item][ix].funBody = v"
                             v-show="activeScript === it.funName"
                             :value="it.funBody"
                             :key="it.funName"
                             :mode="'javascript'"
                             :ref="it.funName">
                </code-editor>
              </template>
            </template>
            <template v-else>
              <code-editor @input="v=>pageScript[item] = v"
                           :value="pageScript[item]"
                           v-show="activeScript === item"
                           :mode="'javascript'"
                           :ref="item">
              </code-editor>
            </template>
          </template>
        </div>
        <div class="dialog-script-con" v-if="tabs === 'data'">
          <el-form ref="form" style="padding: 20px;box-sizing: border-box"
                   size="small"
                   :model="formData"
                   :rules="rules"
                   label-width="120px">
            <el-row>
              <el-col :span="24">
                <el-form-item label="名称" prop="name">
                                <span slot="label">
                                    名称
                                     <el-tooltip effect="light"
                                                 content="禁止使用javaScript关键字（严格遵守javaScript命名规范）">
                                        <i class="el-icon-info"></i>
                                     </el-tooltip>
                                </span>
                  <el-input v-model="formData.name"></el-input>
                </el-form-item>
              </el-col>
            </el-row>
            <el-row>
              <el-col :span="24">
                <el-form-item label="描述">
                  <el-input resize="none" rows="4" type="textarea"
                            v-model="formData.remark"></el-input>
                </el-form-item>
              </el-col>
            </el-row>
            <el-row>
              <el-col :span="24">
                <el-form-item label="请求方法" prop="requestType">
                  <el-radio-group v-model="formData.requestType">
                    <el-radio-button label="get">GET</el-radio-button>
                    <el-radio-button label="post">POST</el-radio-button>
                    <el-radio-button label="put">PUT</el-radio-button>
                    <el-radio-button label="delete">DELETE</el-radio-button>
                  </el-radio-group>
                </el-form-item>
              </el-col>
            </el-row>
            <el-row>
              <el-col :span="24">
                <el-form-item label="请求数据格式">
                  <el-radio-group v-model="formData.requestDataType">
                    <el-radio-button label="params">params</el-radio-button>
                    <el-radio-button label="data">data</el-radio-button>
                  </el-radio-group>
                </el-form-item>
              </el-col>
            </el-row>
            <el-row>
              <el-col :span="24">
                <el-form-item label="是否自动请求">
                                <span slot="label">
                                    是否自动请求
                                     <el-tooltip effect="light" content="页面加载时就请求该接口">
                                        <i class="el-icon-info"></i>
                                     </el-tooltip>
                                </span>
                  <el-switch v-model="formData.autoRequest"></el-switch>
                </el-form-item>
              </el-col>
            </el-row>
            <el-row>
              <el-col :span="24">
                <el-form-item label="请求地址" prop="url">
                  <el-input v-model="formData.url"></el-input>
                </el-form-item>
              </el-col>
            </el-row>
            <el-row>
              <el-col :span="24">
                <el-form-item label="返回参数结构">
                                 <span slot="label">
                                    返回参数结构
                                     <el-tooltip effect="light"
                                                 content="返回值取值的结构">
                                        <i class="el-icon-info"></i>
                                     </el-tooltip>
                                </span>
                  <div style="display: flex;flex-direction: row;justify-content: space-between">
                    res
                    <el-input style="width: 90%" v-model="formData.structure"></el-input>
                  </div>
                </el-form-item>
              </el-col>
            </el-row>
            <el-row>
              <el-col :span="24">
                <el-form-item label="请求参数">
                  <el-button icon="el-icon-plus" type="primary" size="mini" @click="add('RP')">添加
                  </el-button>
                  <ul style="list-style: none;padding: 0">
                    <li v-for="(item, idx) in formData.requestParameterList" :key="idx">
                      <div class="li">
                        <el-col :span="6">
                          <el-input placeholder="key" v-model="item.key"
                                    size="mini"></el-input>
                        </el-col>
                        <span>&nbsp;</span>
                        <el-input placeholder="value" v-model="item.value"
                                  size="mini"></el-input>
                        <el-button type="text" icon="el-icon-delete"
                                   @click="del(idx,'RP')"></el-button>
                      </div>
                    </li>
                  </ul>
                </el-form-item>
              </el-col>
            </el-row>
            <el-row>
              <el-col :span="24">
                <el-form-item label="请求头信息">
                  <el-button icon="el-icon-plus" type="primary" size="mini" @click="add('RH')">添加
                  </el-button>
                  <ul style="list-style: none;padding: 0">
                    <li v-for="(item, idx) in formData.requestHeaderList" :key="idx">
                      <div class="li">
                        <el-input placeholder="key" v-model="item.key" size="mini"></el-input>
                        <span>:</span>
                        <el-input placeholder="value" v-model="item.value"
                                  size="mini"></el-input>
                        <el-button type="text" icon="el-icon-delete"
                                   @click="del(idx,'RH')"></el-button>
                      </div>
                    </li>
                  </ul>
                </el-form-item>
              </el-col>
            </el-row>
            <el-row>
              <el-col :span="24">
                <el-form-item>
                                    <span slot="label">
                                        请求前对参数的处理函数
                                         <el-tooltip effect="light"
                                                     content="arguments 为参数集合">
                                            <i class="el-icon-info"></i>
                                         </el-tooltip>
                                    </span>
                  <code-editor @input="v=>this.formData.beforeFun = v"
                               :value="this.formData.beforeFun"
                               :mode="'javascript'"
                               ref="beforeFun">
                  </code-editor>
                </el-form-item>
              </el-col>
            </el-row>
            <el-row>
              <el-col :span="24">
                <el-form-item>
                                    <span slot="label">
                                        请求成功对结果的处理函数
                                         <el-tooltip effect="light"
                                                     content="res 为成功的数据集">
                                            <i class="el-icon-info"></i>
                                         </el-tooltip>
                                    </span>
                  <code-editor @input="v=>this.formData.successFun = v"
                               :value="this.formData.successFun"
                               :mode="'javascript'"
                               ref="successFun">
                  </code-editor>
                </el-form-item>
              </el-col>
            </el-row>
            <el-row>
              <el-col :span="24">
                <el-form-item>
                                    <span slot="label">
                                        请求失败异常的处理函数
                                         <el-tooltip effect="light"
                                                     content="err 为失败信息">
                                            <i class="el-icon-info"></i>
                                         </el-tooltip>
                                    </span>
                  <code-editor @input="v=>this.formData.errorFun = v"
                               :value="this.formData.errorFun"
                               :mode="'javascript'"
                               ref="errorFun">
                  </code-editor>
                </el-form-item>
              </el-col>
            </el-row>
          </el-form>
        </div>

        <div class="dialog-script-data">
          <el-tabs v-model="tabs" type="border-card">
            <el-tab-pane name="script" label="脚本">
              <p>
                <el-button size="mini" type="primary" @click="funVisible=true,funDialog='add'">
                  添加方法
                </el-button>
              </p>

              <div :class="{'active':activeScript==='data'}" class="dsd-item" @click="edit('data')">data
              </div>
              <el-collapse :value="[1]">
                <el-collapse-item :name="1" title="methods">
                  <template v-for="(it,ix) in pageScript.methods">
                    <div :class="{'active':activeScript===it.funName}"
                         class="dsd-item dsdContent"
                         :key="ix"
                         @click="edit(it.funName)">
                        <div class="dsdDetail">
                           {{ it.funName }}
                          <span style="font-size: 12px">
                            （{{ it.funRemark ? it.funRemark : '-' }}）
                          </span>
                         </div>
                     

                      <div class="after-btn">
                        <el-button type="text" icon="el-icon-edit-outline"
                                   @click.prevent.stop="funVisible=true,formScript=deepCopy(it),funDialog='edit'"></el-button>
                        <el-button type="text" icon="el-icon-delete"
                                   @click="delFun(ix)"></el-button>
                      </div>
                    </div>
                  </template>
                </el-collapse-item>
              </el-collapse>
              <div :class="{'active':activeScript==='mounted'}" class="dsd-item" @click="edit('mounted')">
                mounted
              </div>
              <div :class="{'active':activeScript==='created'}" class="dsd-item" @click="edit('created')">
                created
              </div>
            </el-tab-pane>
            <el-tab-pane name="data" label="数据源">
              <p>
                <el-button size="mini" @click="addDataSource">添加数据源</el-button>
                <el-button size="mini" type="primary" @click="saveDataSource">保存数据源</el-button>
              </p>
              <div class="list">
                <template v-for="(item,idx) in designer.dataSource">
                  <div class="list-item" :class="{'activeDataSource':formIdx===idx}" :key="idx"
                       @click.prevent.stop="editDataSource(item,idx)">
                    <div>
                      <el-tag>{{ item.name }}</el-tag>
                      <div style="font-size: 12px;margin-top: 10px;text-indent: 10px">描述：
                        {{ item.remark }}
                      </div>
                    </div>
                    <div class="list-item-operation">
                      <el-button type="text" icon="el-icon-delete"
                                 @click.prevent.stop="delDataSource(idx)"></el-button>
                    </div>
                  </div>
                </template>
              </div>
            </el-tab-pane>
          </el-tabs>
        </div>
      </div>

      <div slot="footer" style="text-align: right">
        <el-button size="small" @click="close">关闭</el-button>
      </div>

      <el-dialog width="450px" title="方法"
                 :visible.sync="funVisible"
                 :modal-append-to-body="true"
                 :destroy-on-close="true"
                 :append-to-body="true">
        <el-form size="mini" ref="fs" :model="formScript"
                 :rules="rulesScript"
                 label-width="65px">
          <el-form-item label="方法名" prop="funName">
            <el-input v-model="formScript.funName"></el-input>
          </el-form-item>
          <el-form-item label="备注">
            <el-input v-model="formScript.funRemark"></el-input>
          </el-form-item>
        </el-form>
        <div slot="footer" style="text-align: right">
          <el-button size="mini" type="primary" @click="addMethods">确定</el-button>
          <el-button size="mini" @click="closeMethods">取消</el-button>
        </div>
      </el-dialog>
    </el-dialog>
  </div>
</template>

<script>
import CodeEditor from "@/components/code-editor/index.vue";
import Draggable from "vuedraggable";

export default {
  name: "scriptEdit",
  components: { Draggable, CodeEditor },
  props: {
    visible: {
      type: Boolean,
      default: () => false,
    },
    type: {
      type: String,
      default: () => "",
    },
    scriptType: {
      type: String,
      default: () => "",
    },
    designer: Object,
  },
  data() {
    return {
      tabs: "script",
      activeScript: "data",
      activeDataSource: "",

      formIdx: -1,
      formData: {
        name: "",
        remark: "",
        requestType: "get",
        url: "",
        requestDataType: "params",
        autoRequest: false,
        //返回参数的结构
        structure: "data.data",
        //请求参数
        requestParameterList: [],
        //请求头
        requestHeaderList: [],

        //请求前对参数的处理函数
        beforeFun: `console.log('arguments')`,
        //请求成功对结果的处理函数
        successFun: `console.log('res')`,
        //请求失败异常的处理函数
        errorFun: `console.log('err')`,
      },
      form: {
        name: "",
        remark: "",
        requestType: "get",
        url: "",
        requestDataType: "params",
        autoRequest: false,
        //返回参数的结构
        structure: "data.data",
        //请求参数
        requestParameterList: [],
        //请求头
        requestHeaderList: [],

        //请求前对参数的处理函数
        beforeFun: "",
        //请求成功对结果的处理函数
        successFun: "",
        //请求失败异常的处理函数
        errorFun: "",
      },
      rules: {
        name: [{ required: true, message: "请输入名称", trigger: "blur" }],
        requestType: [
          { required: true, message: "请选择请求方式", trigger: "change" },
        ],
        url: [{ required: true, message: "请输入请求地址", trigger: "blur" }],
      },

      funVisible: false,
      funDialog: "add",
      formScript: {
        funName: "",
        funBody: "",
        funRemark: "",
        id: "",
      },
      rulesScript: {
        funName: [{ required: true, message: "请输入名称", trigger: "blur" }],
      },

      filterText: "",
      treeData: [
        {
          label: "页面脚本",
          unShowPopover: true,
          children: [
            {
              label: "获取页面所有数据",
              details: {
                label: "获取页面所有数据",
                subLabel: "getFormData",
                script: `this.getFormData().then(res=>{
                                    //res为数据集
                                })`,
              },
            },
            {
              label: "设置页面所有数据",
              details: {
                label: "设置页面所有数据",
                subLabel: "setFormData",
                script: `this.setFormData('设置的数据')`,
              },
            },
            {
              label: "获取单个字段数据",
              details: {
                label: "获取单个字段数据",
                subLabel: "getFieldValue",
                script: `this.getFieldValue('字段名')`,
              },
            },
            {
              label: "设置单个字段数据",
              details: {
                label: "设置单个字段数据",
                subLabel: "setFieldValue",
                script: `this.setFieldValue('字段名')`,
              },
            },
            {
              label: "禁用整个表单",
              details: {
                label: "禁用整个表单",
                subLabel: "disableForm",
                script: `this.disableForm()`,
              },
            },
            {
              label: "重置整个表单",
              details: {
                label: "重置整个表单",
                subLabel: "resetForm",
                script: `this.resetForm()`,
              },
            },
            {
              label: "校验整个表单",
              details: {
                label: "校验整个表单",
                subLabel: "validateForm",
                script: `this.validateForm((f)=>{})`,
              },
            },
            {
              label: "获取指定数据源返回值",
              details: {
                label: "获取指定数据源返回值",
                subLabel: "dataSourceMapData.['数据源唯一名称']",
                script: `let data = this.dataSourceMapData.['数据源唯一名称'];//data为指定数据源的数据集`,
              },
            },
            {
              label: "调用指定数据源获取数据",
              details: {
                label: "调用指定数据源获取数据",
                subLabel: "dataSourceMethods.['数据源唯一名称']()",
                script: `this.dataSourceMethods.['数据源唯一名称']().then(res=>{
                                    //res为数据集
                                })`,
              },
            },
          ],
        },
        {
          label: "字符串脚本",
          unShowPopover: true,
          children: [
            {
              label: "字符串处理",
              unShowPopover: true,
              children: [
                {
                  label: "替换",
                  details: {
                    label: "替换字符串",
                    subLabel: "replace",
                    script: `const str = "Hello, world!";<br/>console.log(str.replace("world", "body")); `,
                  },
                },
                {
                  label: "分割",
                  details: {
                    label: "分割字符串",
                    subLabel: "split",
                    script: `const str = "today-is-Tuesday";<br/>console.log(str.split("-"));`,
                  },
                },
                {
                  label: "拼接",
                  details: {
                    label: "拼接字符串",
                    subLabel: "join",
                    script: `const str = ['A', 'B', 'C'];<br/>console.log(str.join("-"));`,
                  },
                },
                {
                  label: "包含",
                  details: {
                    label: "是否包含某个字符",
                    subLabel: "includes",
                    script: `const res = str.includes("子字符串");`,
                  },
                },
                {
                  label: "去除两端空白",
                  details: {
                    label: "去除两端空白",
                    subLabel: "trim",
                    script: `const str = "       builder        ";</br>console.log(str.trim()); // "builder"`,
                  },
                },
              ],
            },
          ],
        },
      ],
      treeProps: {
        children: "children",
        label: "label",
      },

      com: ["data", "methods", "mounted", "created"],
    };
  },
  computed: {
    pageScript() {
      return this.designer.pageScript;
    },
  },
  methods: {
    test(node, data) {
      console.log(node, data);
    },
    add(type) {
      let m = type === "RP" ? "requestParameterList" : "requestHeaderList";
      this.formData[m].push({ key: "", value: "" });
    },
    delDataSource(idx) {
      this.designer.dataSource.splice(idx, 1);
      this.addDataSource();
    },
    editDataSource(item, idx) {
      this.activeDataSource = idx;
      this.tabs = "data";
      this.formData = this.deepCopy(item);
      this.formIdx = idx;
      this.visible = true;
    },
    addDataSource() {
      this.formData = this.deepCopy(this.form);
      this.formIdx = -1;
    },
    del(index, type) {
      let m = type === "RP" ? "requestParameterList" : "requestHeaderList";
      this.formData[m].splice(index, 1);
    },
    saveDataSource() {
      this.$refs["form"].validate((f) => {
        if (f) {
          if (this.formIdx === -1) {
            let names = this.designer.dataSource.map((i) => i.name);
            if (names.includes(this.formData.name)) {
              this.$message.warning("该数据源名称已存在！");
              return;
            }
            this.designer.dataSource.push(this.deepCopy(this.formData));
          } else {
            this.designer.dataSource[this.formIdx] = this.deepCopy(
              this.formData
            );
          }
          this.$message.success("保存成功");
        }
      });
    },

    delFun(index) {
      this.designer.pageScript.methods.splice(index, 1);
    },
    addMethods() {
      this.$refs["fs"].validate((f) => {
        if (f) {
          if (this.funDialog === "add") {
            this.formScript.id = this.getOnlyId();
            this.pageScript.methods.push(this.formScript);
          }
          if (this.funDialog === "edit") {
            let index = this.pageScript.methods
              .map((i) => i.id)
              .indexOf(this.formScript.id);
            this.pageScript.methods[index] = this.deepCopy(this.formScript);
          }

          this.closeMethods();
        }
      });
    },
    closeMethods() {
      this.funVisible = false;
      this.formScript = {
        funName: "",
        funBody: "",
        funRemark: "",
        id: "",
      };
    },

    edit(type) {
      this.activeScript = type;
    },

    close() {
      this.$emit("update:visible", false);
    },
    filterNode(value, data) {
      if (!value) return true;
      return data.label.indexOf(value) !== -1;
    },
  },
  mounted() {},
  watch: {
    filterText(val) {
      this.$refs.tree_.filter(val);
    },
    type: {
      //组件属性变动后，立即保存表单JSON！！
      deep: true,
      handler(val) {
        if (val) {
          this.tabs = val;
        }
      },
    },
    scriptType: {
      //组件属性变动后，立即保存表单JSON！！
      deep: true,
      handler(val) {
        if (val) {
          this.activeScript = val;
        }
      },
    },
  },
};
</script>

<style scoped lang="scss">
.dialog-script {
  width: 100%;
  height: 70vh;
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  flex-wrap: nowrap;

  $tip: 300px;
  $data: 300px;

  > div {
    height: 100%;
  }

  .dialog-script-tip {
    width: $tip;
    padding: 0 15px;
    box-sizing: border-box;

    .dst-tree {
      padding-top: 15px;
      height: calc(100% - 45px);
      overflow-y: scroll;

      &::-webkit-scrollbar {
        width: 4px;
      }
    }
  }

  .dialog-script-con {
    width: calc(100% - #{$tip} - #{$data});
    border: 10px solid #f2f2f2;
    box-sizing: border-box;
    overflow-y: scroll;

    &::-webkit-scrollbar {
      width: 4px;
    }

    .li {
      display: flex;
      flex-direction: row;
      justify-content: space-between;
      flex-wrap: nowrap;
      margin-bottom: 5px;
      line-height: 28px;

      .el-input {
        padding: 0 5px;
      }
    }
  }

  .dialog-script-data {
    width: $data;
    p {
      margin-top: 0;
    }

    .list {
      width: 100%;
      height: calc(100% - 40px);
      margin-top: 10px;
      overflow-y: scroll;

      .list-item {
        width: 100%;
        border: 1px solid #ddd;
        border-radius: 4px;
        padding: 5px 10px;
        box-sizing: border-box;
        display: flex;
        flex-direction: row;
        justify-content: space-between;
        flex-wrap: nowrap;
        margin-bottom: 5px;
        cursor: pointer;

        .list-item-operation {
          display: flex;
          flex-direction: row;
          justify-content: space-between;
          flex-wrap: nowrap;

          .el-button {
            padding: 0;
          }
        }
      }

      .activeDataSource {
        background: rgba(242, 242, 242, 0.5);
        border: 1px solid #1e9fff;
      }
    }

    ::v-deep .el-tabs {
      width: 100%;
      height: 100%;
      .el-tabs__content {
        height: calc(100% - 80px);
      }
      .el-tab-pane {
        height: 100%;
      }
      .el-collapse {
        border: none;

        .el-collapse-item {
          > div {
            border: none;

            .el-collapse-item__header {
              height: 30px;
              line-height: 30px;
              padding-left: 10px;
              border: none;
              background: #f2f2f2;
              color: #606266;
            }

            .el-collapse-item__content {
              padding-bottom: 0;
              padding-left: 15px;
              box-sizing: border-box;
            }
          }
        }
      }
    }
  .dsdContent{
    width: 100%;
    box-sizing: border-box;
    padding-right: 80px;
    .dsdDetail{
      width: 100%;
      text-overflow: ellipsis;
      overflow: hidden;
      white-space: nowrap;
    }
  }
    .dsd-item {
      height: 30px;
      line-height: 30px;
      padding-left: 10px;
      cursor: pointer;
      position: relative;

      &:hover {
        background: rgba(242, 242, 242, 0.5);
      }

      .after-btn {
        position: absolute;
        height: 30px;
        top: 0;
        right: 10px;
      }
    }

    .active {
      background: #1e9fff !important;
      color: white;
    }
  }
}
</style>

<style lang="scss">
.dst-tree {
  .el-tree {
    > div {
      .el-tree-node__content {
        height: 35px;
        line-height: 35px;
      }
    }
  }
}
</style>
